package ansible

import (
	"errors"
	"fmt"
)

// AnsibleError 表示 Ansible 操作中的错误
type AnsibleError struct {
	Op      string // 操作名称
	Command string // 执行的命令
	Err     error  // 底层错误
	Stdout  []byte // 标准输出
	Stderr  []byte // 标准错误输出
}

func (e *AnsibleError) Error() string {
	if e.Err != nil {
		return fmt.Sprintf("ansible %s failed: %v", e.Op, e.Err)
	}
	return fmt.Sprintf("ansible %s failed", e.Op)
}

func (e *AnsibleError) Unwrap() error {
	return e.Err
}

// 预定义的错误类型
var (
	ErrEmptyModule     = errors.New("module name cannot be empty")
	ErrInvalidInventory = errors.New("invalid inventory type")
	ErrFileNotFound    = errors.New("playbook file not found")
	ErrInvalidTimeout  = errors.New("invalid timeout value")
	ErrContextCanceled = errors.New("operation was canceled")
)

// NewAnsibleError 创建一个新的 AnsibleError
func NewAnsibleError(op, command string, err error, stdout, stderr []byte) *AnsibleError {
	return &AnsibleError{
		Op:      op,
		Command: command,
		Err:     err,
		Stdout:  stdout,
		Stderr:  stderr,
	}
}

// IsAnsibleError 检查错误是否为 AnsibleError 类型
func IsAnsibleError(err error) bool {
	var ansibleErr *AnsibleError
	return errors.As(err, &ansibleErr)
}

// GetAnsibleError 从错误中提取 AnsibleError
func GetAnsibleError(err error) (*AnsibleError, bool) {
	var ansibleErr *AnsibleError
	if errors.As(err, &ansibleErr) {
		return ansibleErr, true
	}
	return nil, false
}
